#include <windows.h>
#include <stdio.h>

// 全局钩子句柄
HHOOK g_mouse_hook = NULL;

// 鼠标钩子回调函数
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode >= 0) {
        // 只监听垂直滚动
        if (wParam == WM_MOUSEWHEEL) {
            MSLLHOOKSTRUCT* pMouseStruct = (MSLLHOOKSTRUCT*)lParam;

            // 获取滚动增量
            int delta = GET_WHEEL_DELTA_WPARAM(pMouseStruct->mouseData);

            // 使用英文输出避免乱码
            printf("Mouse Wheel: %d (Position: %d, %d)\n",
                   delta, pMouseStruct->pt.x, pMouseStruct->pt.y);
            // 在 LowLevelMouseProc 中可以添加如下检查
            LRESULT extraInfo = GetMessageExtraInfo();
            // 简单判断是否可能是模拟事件
            if (extraInfo == 0) {
                printf(" [Possibly simulated]\n");
            } else {
                printf(" [Real mouse]\n");
            }
        }
    }

    // 调用下一个钩子
    return CallNextHookEx(g_mouse_hook, nCode, wParam, lParam);
}

// 安装鼠标钩子
BOOL InstallMouseHook() {
    g_mouse_hook = SetWindowsHookEx(
            WH_MOUSE_LL,           // 低级别鼠标钩子
            LowLevelMouseProc,     // 回调函数
            GetModuleHandle(NULL), // 当前实例句柄
            0                      // 所有线程
    );

    if (g_mouse_hook == NULL) {
        printf("Install mouse hook failed, error code: %lu\n", GetLastError());
        return FALSE;
    }

    printf("Mouse hook installed successfully\n");
    return TRUE;
}

// 卸载鼠标钩子
void UninstallMouseHook() {
    if (g_mouse_hook) {
        UnhookWindowsHookEx(g_mouse_hook);
        g_mouse_hook = NULL;
        printf("Mouse hook uninstalled\n");
    }
}

// 消息循环
void MessageLoop() {
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);

        // 检查ESC键退出
        if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) {
            printf("ESC key detected, exiting...\n");
            break;
        }
    }
}

int main() {
    // 禁用系统控制台的输出缓存，以使得能够实时打印输出
    setbuf(stdout, 0);
    printf("=== Global Mouse Wheel Listener ===\n");
    printf("Function: Listen and display mouse wheel events\n");
    printf("Press ESC key to exit\n\n");

    // 安装鼠标钩子
    if (!InstallMouseHook()) {
        printf("Failed to install mouse hook, program exit\n");
        return 1;
    }

    printf("Start listening for mouse wheel events...\n");
    printf("Scroll mouse anywhere to see output\n\n");

    // 运行消息循环
    MessageLoop();

    // 清理资源
    UninstallMouseHook();

    printf("Program exited\n");
    return 0;
}
